#!/bin/bash

# 配置参数
SOURCE_DIR="/home/cys/www/data/localhost"
TEMP_DIR="/home/cys/www/ossutil/temp"
OSS_BUCKET="oss://log-bdp-eu/"  # 修改为你的OSS bucket地址
TIME_THRESHOLD=180  # 2小时 = 120分钟
LOG_DIR="/home/cys/www/ossutil/logs"
LOG_FILE="${LOG_DIR}/upload_log_to_oss_$(date '+%Y-%m-%d').log"
FILE_CONFIG="/home/cys/www/ossutil/ossutils_eu.config"


# 创建日志目录（如果不存在）
mkdir -p "$LOG_DIR"

# 用于存储各个时间戳对应的文件行数日志文件名
declare -A file_line_logs


# 创建日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "========== 开始备份最近2小时的文件 =========="

# 获取非回环的IPv4地址并赋值
LOCAL_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+' | grep -v '^127.' | head -n 1 | cut -d '/' -f 1)

# 关键：导出变量使其在子进程中可用
export LOCAL_IP

# 输出结果验证
log "当前IP地址: $LOCAL_IP"
OSS_BUCKET="oss://log-bdp-eu/$LOCAL_IP"

log "OSS_BUCKET: $OSS_BUCKET"


# 检查配置文件是否存在
if [ ! -f "$FILE_CONFIG" ]; then
    log "错误: OSS配置文件不存在: $FILE_CONFIG"
    log "请运行: ossutil config -c $FILE_CONFIG 来配置OSS"
    log "配置示例:"
    log "  endpoint = oss-eu-central-1.aliyuncs.com"
    log "  accessKeyID = YOUR_ACCESS_KEY_ID"
    log "  accessKeySecret = YOUR_ACCESS_KEY_SECRET"
    exit 1
fi

log "找到配置文件: $FILE_CONFIG"

# 测试OSS连接
log "测试OSS连接..."
oss_test_output=$(ossutil --config-file $FILE_CONFIG ls "$OSS_BUCKET" 2>&1)
oss_test_result=$?

if [ $oss_test_result -ne 0 ]; then
    log "错误: 无法连接到OSS bucket: $OSS_BUCKET"
    log "详细错误信息:"
    echo "$oss_test_output" | tee -a "$LOG_FILE"
    log ""
    log "可能的原因:"
    log "1. 配置文件 $FILE_CONFIG 中的endpoint不正确（应该是欧洲区域的endpoint）"
    log "2. accessKeyID 或 accessKeySecret 不正确"
    log "3. 当前服务器无法访问OSS欧洲区域（网络问题或防火墙限制）"
    log "4. OSS bucket不存在或没有访问权限"
    log ""
    log "请检查配置文件内容:"
    if [ -f "$FILE_CONFIG" ]; then
        log "配置文件前几行:"
        head -n 10 "$FILE_CONFIG" | grep -v "accessKeySecret" | tee -a "$LOG_FILE"
    fi
    log ""
    log "建议操作:"
    log "1. 从欧洲服务器拷贝配置文件: scp user@eu-server:$FILE_CONFIG $FILE_CONFIG"
    log "2. 或重新配置: ossutil config -c $FILE_CONFIG"
    log "3. 测试网络连通性: ping oss-eu-central-1.aliyuncs.com"
    exit 1
fi
log "OSS连接测试成功"

# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
    log "错误: 源目录 $SOURCE_DIR 不存在"
    exit 1
fi

# 创建临时目录
mkdir -p "$TEMP_DIR"

# 获取当前时间戳（分钟）
current_time=$(date +%s)
current_time_minutes=$((current_time / 60))

# 计数器
total_files=0
processed_files=0
uploaded_files=0
failed_files=0

# 遍历源目录下的所有子目录
for subdir in "$SOURCE_DIR"/*/ ; do
    if [ ! -d "$subdir" ]; then
        continue
    fi
    
    subdir_name=$(basename "$subdir")
    log "处理子目录: $subdir_name"
    
    # 遍历子目录下的所有文件
    for file in "$subdir"* ; do
        if [ ! -f "$file" ]; then
            continue
        fi
        
        filename=$(basename "$file")
        total_files=$((total_files + 1))
        
        # 从文件名中提取时间戳
        # 文件名格式: widget_show.2025-11-21_11.0.txt
        # 提取日期和小时部分
        if [[ $filename =~ ([0-9]{4}-[0-9]{2}-[0-9]{2})_([0-9]{2}) ]]; then
            file_date="${BASH_REMATCH[1]}"
            file_hour="${BASH_REMATCH[2]}"
            
            # 转换为时间戳
            file_datetime="${file_date} ${file_hour}:00:00"
            file_timestamp=$(date -d "$file_datetime" +%s 2>/dev/null)
            
            if [ $? -ne 0 ]; then
                log "  警告: 无法解析文件时间 $filename"
                continue
            fi
            
            file_time_minutes=$((file_timestamp / 60))
            time_diff=$((current_time_minutes - file_time_minutes))
            
            # 检查文件是否在2小时内
            if [ $time_diff -le $TIME_THRESHOLD ] && [ $time_diff -ge 0 ]; then
                log "  找到符合条件的文件: $filename (距今 $time_diff 分钟)"
                processed_files=$((processed_files + 1))
                
                # 计算文件行数
                file_line_count=$(wc -l < "$file" 2>/dev/null || echo "0")
                log "  文件行数: $file_line_count"
                
                # 生成文件行数统计文件名（基于文件时间戳）
                file_timestamp="${file_date}_${file_hour}"
                file_line_log="${LOG_DIR}/log_file_line_${file_timestamp}.txt"
                
                # 记录到对应时间戳的文件行数统计文件：目录/文件名/行数
                echo "${subdir_name}/${filename}/${file_line_count}" >> "$file_line_log"
                
                # 记录该时间戳的日志文件（用于后续上传）
                file_line_logs["$file_timestamp"]="$file_line_log"
                
                # 创建临时子目录
                temp_subdir="$TEMP_DIR/$subdir_name"
                mkdir -p "$temp_subdir"
                
                # 拷贝文件到临时目录
                cp "$file" "$temp_subdir/"
                if [ $? -ne 0 ]; then
                    log "  错误: 拷贝文件失败 $filename"
                    failed_files=$((failed_files + 1))
                    continue
                fi
                
                # 进入临时目录进行压缩
                cd "$temp_subdir" || continue
                
                # 压缩文件
                gzip -f "$filename"
                if [ $? -ne 0 ]; then
                    log "  错误: 压缩文件失败 $filename"
                    failed_files=$((failed_files + 1))
                    rm -f "$filename"
                    continue
                fi
                
                compressed_file="${filename}.gz"
                log "  压缩完成: $compressed_file"
                
                # 上传到OSS
                oss_path="${OSS_BUCKET}/${subdir_name}/${compressed_file}"
                
                # 先检查OSS上是否存在该目录，如果不存在则创建
                oss_dir="${OSS_BUCKET}/${subdir_name}/"
                log "  检查OSS目录: $oss_dir"
                ossutil --config-file $FILE_CONFIG ls "$oss_dir" >/dev/null 2>&1
                if [ $? -ne 0 ]; then
                    log "  OSS目录不存在，尝试创建: $oss_dir"
                    ossutil --config-file $FILE_CONFIG mkdir "$oss_dir" 2>&1 | tee -a "$LOG_FILE"
                fi
                
                log "  开始上传: $oss_path"
                ossutil --config-file $FILE_CONFIG cp "$compressed_file" "$oss_path" --update 2>&1 | tee -a "$LOG_FILE"
                
                if [ ${PIPESTATUS[0]} -eq 0 ]; then
                    log "  上传成功: $oss_path"
                    uploaded_files=$((uploaded_files + 1))
                    
                    # 删除临时压缩文件
                    rm -f "$compressed_file"
                    log "  已删除临时文件: $compressed_file"
                else
                    log "  错误: 上传失败 $compressed_file"
                    failed_files=$((failed_files + 1))
                fi
                
                cd - > /dev/null
            fi
        else
            log "  跳过: 文件名格式不匹配 $filename"
        fi
    done
done

# 清理空的临时子目录
find "$TEMP_DIR" -type d -empty -delete 2>/dev/null

# 上传所有文件行数统计文件到OSS
if [ ${#file_line_logs[@]} -gt 0 ]; then
    log "========== 开始上传文件行数统计文件 =========="
    
    # 检查file_line目录是否存在，不存在则创建
    oss_file_line_dir="${OSS_BUCKET}/file_line/"
    log "检查OSS目录: $oss_file_line_dir"
    ossutil --config-file $FILE_CONFIG ls "$oss_file_line_dir" >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        log "OSS目录不存在，尝试创建: $oss_file_line_dir"
        ossutil --config-file $FILE_CONFIG mkdir "$oss_file_line_dir" 2>&1 | tee -a "$LOG_FILE"
    fi
    
    # 遍历所有文件行数统计文件并上传
    for timestamp in "${!file_line_logs[@]}"; do
        file_line_log="${file_line_logs[$timestamp]}"
        
        if [ -f "$file_line_log" ] && [ -s "$file_line_log" ]; then
            file_line_log_name=$(basename "$file_line_log")
            oss_file_line_path="${OSS_BUCKET}/file_line/${file_line_log_name}"
            
            log "上传文件行数统计文件: $file_line_log_name -> $oss_file_line_path"
            ossutil --config-file $FILE_CONFIG cp "$file_line_log" "$oss_file_line_path" --update 2>&1 | tee -a "$LOG_FILE"
            
            if [ ${PIPESTATUS[0]} -eq 0 ]; then
                log "  上传成功: $oss_file_line_path"
                log "  文件内容预览 (前5行):"
                head -n 5 "$file_line_log" | while read line; do log "    $line"; done
            else
                log "  错误: 上传失败"
            fi
        fi
    done
    
    log "文件行数统计文件上传完成，共 ${#file_line_logs[@]} 个文件"
else
    log "没有找到符合条件的文件，跳过上传文件行数统计"
fi

# 输出统计信息
log "========== 备份完成 =========="
log "总文件数: $total_files"
log "处理文件数: $processed_files"
log "上传成功: $uploaded_files"
log "失败文件: $failed_files"

# 返回状态码
if [ $failed_files -gt 0 ]; then
    exit 1
else
    exit 0
fi
